﻿/* GameObjectManager 
 * Manages the spawning of files in view mode,
 * and manages the future modes
 * 
 * 
 * 
 * 
 */


using UnityEngine; //default
using System.Collections; //default
using System.Collections.Generic; //For lists
using System.IO ;//writing/reading to/from disk for the FileViewer



public class GameObjectManager : MonoBehaviour {
	public enum Modes {FileViewer,Other};
	public Modes Mode = Modes.FileViewer;
	/* File Types */
	public enum FileTypes {Text, Image, Program, Folder, Music, Video, Other};
	public FileTypes AvaliableFileTypes = FileTypes.Text;
	public GameObject[] Prefabs;

	/* Progressive loading */
	public bool b_PL_IsDone;
	public bool b_PL_IsLoading;
	public bool b_PL_ImagesLoadOnStart;
	public bool b_PL_NameObjects;
	private float f_PL_Time;
	public float f_PL_Delay;
	private int i_PL_CurObject;
	public float f_PL_Spacing;
	public bool b_PL_SquareCount;
	public float f_PL_CountBeforeNewRow;
	private int i_PL_X;
	private int i_PL_Y;


	/* FileViewer */
	public GameObject[] aG_FV_AllGameObjects;
	public string s_FV_CurDir;
	public List<string> lS_FV_Files;
	public List<string> lS_FV_Folders;
	public List<FileInfo> lS_FV_FilesAndFolders;
	[System.Serializable]
	public class FileInfo{
		public FileTypes FileType;
		public string FriendlyName;
		public int Index;
	}


	//Start my own start function
	void Start () { Setup(); }
	public void Setup(){
		//if theres some active objects in the fileviewer
		if(aG_FV_AllGameObjects.Length != 0){
			for(int Index = 0; Index < aG_FV_AllGameObjects.Length; Index++){
				Destroy(aG_FV_AllGameObjects[Index]);
			}
		}
		aG_FV_AllGameObjects = new GameObject[0];

		System.GC.Collect();
		Resources.UnloadUnusedAssets();


		//Are we starting the file viewer?
		if(Mode == Modes.FileViewer){
			//prep Progressive load for a new run
			b_PL_IsDone = false;
			b_PL_IsLoading = true;
			i_PL_CurObject = 0;
			f_PL_Time = 0;
			i_PL_X = 0;
			i_PL_Y = 0;
			//get the current folder and set up the fileinfos
			CurDir();
			BuildFileList();
			//new clean array
			aG_FV_AllGameObjects = new GameObject[lS_FV_FilesAndFolders.Count];
		}



	}

	//Every Frame
	void Update () {
		if(b_PL_IsLoading){
			f_PL_Time+=Time.deltaTime;
			if(f_PL_Time >= f_PL_Delay){
				ProgressiveLoad();
				f_PL_Time = 0;
			}
		}

		if(Input.GetKeyDown(KeyCode.F5)){
			Setup();
		}
		if(Input.GetKeyDown(KeyCode.F4)){
			UpDir();
			Setup();
		}

	}

	//Loads game objects one by one with a delay
	void ProgressiveLoad(){
		if(b_PL_IsDone){
			return;
		}
		FileInfo CurFileInfo = lS_FV_FilesAndFolders[i_PL_CurObject];
		GameObject CurGameObj = MakeFilePrefab(CurFileInfo.FileType);
		//add the new object to the all array
		aG_FV_AllGameObjects[i_PL_CurObject] = CurGameObj;
		//setup the new prefab
		if(b_PL_NameObjects){
			CurGameObj.name = "FV Object:"+CurFileInfo.FriendlyName;
		}
		else{
			CurGameObj.name = CurFileInfo.FileType.ToString();
		}
		if(CurGameObj.GetComponent<BaseFile>()){
			CurGameObj.GetComponent<BaseFile>().FileType = CurFileInfo.FileType;
			CurGameObj.GetComponent<BaseFile>().FriendlyName = CurFileInfo.FriendlyName;
			if(CurFileInfo.FileType != FileTypes.Folder){
				CurGameObj.GetComponent<BaseFile>().Ext = ParseExt(CurFileInfo.FriendlyName);
				CurGameObj.GetComponent<BaseFile>().FullPath = lS_FV_Files[CurFileInfo.Index];
			}
			else{
				CurGameObj.GetComponent<BaseFile>().FullPath = lS_FV_Folders[CurFileInfo.Index];
			}
			if(CurFileInfo.FileType == FileTypes.Image){
				if(b_PL_ImagesLoadOnStart){
					CurGameObj.GetComponent<ImageFile>().b_MakeIconOnLoad = true;
				}
			}


			CurGameObj.transform.parent = this.transform;
		}
		if(b_PL_SquareCount){
			f_PL_CountBeforeNewRow = Mathf.Floor(Mathf.Sqrt(lS_FV_FilesAndFolders.Count))-1;
		}
		//get a new grid pos based on spacing float and x y ints
		CurGameObj.transform.position = Make2DGridPosition(f_PL_Spacing,i_PL_X,i_PL_Y);
		//update the x y cords
		i_PL_X++;
		if(i_PL_X > f_PL_CountBeforeNewRow){
			i_PL_Y++;
			i_PL_X = 0;
		}
		//get the next object index ready
		i_PL_CurObject++;
		//did we just hit the end of the list?
		if(i_PL_CurObject >= lS_FV_FilesAndFolders.Count){
			b_PL_IsDone = true;
			b_PL_IsLoading = false;
			i_PL_CurObject = 0;
			f_PL_Time = 0;
			i_PL_X = 0;
			i_PL_Y = 0;
			return;
		}
	}
	//makes the file type prefab
	public GameObject MakeFilePrefab(FileTypes FileType){
		GameObject Output = (GameObject)Instantiate(Prefabs[(int)FileType],Vector3.zero,Quaternion.identity);
		return Output;
	}
	public Vector3 Make2DGridPosition(float Distance, float X, float Y){
		Vector3 Output = new Vector3(X*Distance,0,Y*Distance);
		return Output;
	}

	/* File related */
	void UpDir(){
		if(s_FV_CurDir.Length > 3){
			//is there a slash at the end? if so lets remove it so we dont fake go up a level
			if(s_FV_CurDir[s_FV_CurDir.Length-1] == '/' || s_FV_CurDir[s_FV_CurDir.Length-1] == '\\'){
				s_FV_CurDir = s_FV_CurDir.Substring(0,s_FV_CurDir.Length-2);
			}
			DirectoryInfo NewDI = Directory.GetParent(s_FV_CurDir);
			s_FV_CurDir = NewDI.FullName;
		}
	}
	void CurDir(){
		lS_FV_Files = new List<string>();
		lS_FV_Files.AddRange(Directory.GetFiles(s_FV_CurDir));
		lS_FV_Folders = new List<string>();
		lS_FV_Folders.AddRange(Directory.GetDirectories(s_FV_CurDir));
	}
	void BuildFileList(){
		//build each file
		lS_FV_FilesAndFolders = new List<FileInfo>();
		for(int Index = 0; Index < lS_FV_Files.Count; Index++){
			FileInfo New = new FileInfo();
			New.FriendlyName = ParseFriendlyName(s_FV_CurDir,lS_FV_Files[Index]);
			string TmpExt = ParseExt(New.FriendlyName);
			New.FileType = ParseFileType(TmpExt);
			New.Index = Index;
			lS_FV_FilesAndFolders.Add(New);
		}
		//build each folder
		for(int Index = 0; Index < lS_FV_Folders.Count; Index++){
			FileInfo New = new FileInfo();
			New.FileType = FileTypes.Folder;
			New.FriendlyName = ParseFriendlyName(s_FV_CurDir,lS_FV_Folders[Index]);
			New.Index = Index;
			lS_FV_FilesAndFolders.Add(New);
		}
	}
	public string ParseFriendlyName(string CurDir, string StrInput){
		string Output = StrInput.Substring(CurDir.Length);
		//if we got done and its still has a slash at the begining
		if(Output[0] == '\\' || Output[0] == '/'){
			Output = Output.Substring(1);
		}
		return Output;
	}
	public string ParseExt(string StrInput){
		string Output = "";
		for(int Index = StrInput.Length-1; Index > 0; Index--){
			Output = StrInput[Index]+Output;
			if(StrInput[Index] == '.'){
				break;
			}
		}
		Output = Output.ToLower();
		return Output;
	}
	public FileTypes ParseFileType(string Ext){
		if(Ext == ".txt" || Ext == ".ini"){
			return FileTypes.Text;
		}
		else if(Ext == ".png" || Ext == ".bmp" || Ext == ".jpg" || Ext == ".jpeg"){
			return FileTypes.Image;
		}
		else if(Ext == ".exe" || Ext == ".msi" || Ext == ".com"){
			return FileTypes.Program;
		}
		else if(Ext == ".mp3" || Ext == ".wav" || Ext == ".wma"){
			return FileTypes.Music;
		}
		else{
			return FileTypes.Other;
		}
	}
}
